/**
 *
 */
package com.newer.biz.sys.user.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.newer.biz.sys.user.UserInfoBiz;
import com.newer.commons.constants.CommonConstants;
import com.newer.commons.constants.StateConstants;
import com.newer.commons.result.BizResult;
import com.newer.dao.bean.sys.Role;
import com.newer.dao.bean.sys.User;
import com.newer.dao.bean.sys.UserRole;
import com.newer.dao.mapper.sys.UserMapper;
import com.newer.dao.mapper.sys.UserRoleMapper;
import com.newer.utils.ShiroAuthUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.newer.utils.GenIdUtils.genId;

/**
 * 用户信息业务操作实现类
 *
 * @author xuntj
 * @create 2018-03-14 21:15
 **/
@Component
public class UserInfoBizImpl implements UserInfoBiz {

    /**
     * 日志信息打印
     */
    Logger logger = LogManager.getLogger(this.getClass());

    /**
     * 用户信息数据库操作类
     */
    @Autowired
    UserMapper userMapper;

    /**
     * 用户角色信息数据库操作类
     */
    @Autowired
    UserRoleMapper userRoleMapper;

    /**
     * 分页查询用户信息
     *
     * @param query 查询对象
     * @return
     */
    @Override
    public BizResult<User> queryUserInfoByPages(User query) {
        BizResult<User> bizResult = new BizResult<>();
        try {
            // 分页器进行分页
            Page<User> pageInfo = new Page<>(query.getPageNo(), query.getPageSize());
            // 返回分页结果类
            List<User> users = userMapper.selectByParams(pageInfo, query);
            pageInfo.setRecords(users);
            bizResult.setPageInfo(pageInfo);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("分页查询用户信息失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("分页查询用户信息失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 用户详细信息
     *
     * @param userId 用户ID
     * @return
     */
    @Override
    public BizResult<User> queryUserDetail(String userId) {
        BizResult<User> bizResult = new BizResult<>();
        try {
            // 根据ID查询用户详细信息
            User user = userMapper.selectById(userId);
            // 根据用户ID查询用户拥有的角色信息
            List<UserRole> userRoles = userRoleMapper.selectUserRoles(userId);
            user.setUserRoles(userRoles);
            bizResult.setResult(user);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("查询用户详细信息失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("查询用户详细信息失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 用户注册
     *
     * @param user
     * @return
     */
    @Override
    @Transactional
    public BizResult<?> operateUser(User user) {
        BizResult<?> bizResult = new BizResult<>();
        try {
            if (StringUtils.isBlank(user.getId())) {
                // 判断用户是否存在
                User exitUser = userMapper.selectByLoginName(user.getLoginName());
                // 判断用户是否已经存在
                if (exitUser != null) {
                    bizResult.setMsg("用户已经存在,请重新填写.");
                    return bizResult;
                }
                // 设置ID
                String userId = genId();
                // 设置登录盐
                String salt = genId();
                // 设置用户信息
                user.setSalt(salt);
                user.setId(userId);
                user.setStatus(StateConstants.VALIDE);
                // 根据盐加密用户密码
                user.setLoginPwd(new SimpleHash(CommonConstants.ENCRYP_TYPE,
                        user.getLoginPwd(),
                        salt,
                        CommonConstants.ENCRYP_TIMES).toHex());
                //  添加用户信息
                userMapper.insertSelective(user);
            }
            // 执行修改操作
            else {
                userMapper.updateByPrimaryKeySelective(user);
            }

            // 设置返回成功
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("用户注册失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("用户注册失败,请联系开发人员.");
            // 数据手动回滚
            TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
        }
        return bizResult;
    }

    /**
     * 用户角色授权检查,用户渲染角色授予页面,判断哪些角色已经拥有
     *
     * @param userId
     * @return
     */
    @Override
    public BizResult<Role> userRoleExits(String roleName, String userId, Integer pageNo, Integer pageSize) {
        BizResult<Role> bizResult = new BizResult<>();
        try {
            // 分页器进行分页
            Page<Role> pageInfo = new Page<>(pageNo, pageSize);
            // 返回分页结果类
            List<Role> roles = userRoleMapper.selectRolesExits(pageInfo, userId, roleName);
            pageInfo.setRecords(roles);
            bizResult.setPageInfo(pageInfo);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("用户渲染角色授予页面,判断哪些角色已经拥有失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("用户渲染角色授予页面,判断哪些角色已经拥有失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 用户角色授权
     *
     * @param userRole
     * @return
     */
    @Override
    public BizResult<?> userRoleGrant(UserRole userRole) {
        BizResult<?> bizResult = new BizResult<>();
        try {
            // 判断是否授权
            if (userRole.getGrant()) {
                userRole.setId(genId());
                User user = ShiroAuthUtils.getAuthUser(SecurityUtils.getSubject());
                userRole.setCreater(user.getRealName());
                userRole.setCreateId(user.getId());
                userRoleMapper.insertSelective(userRole);
            } else {
                Map<String, Object> maps = new HashMap<>();
                maps.put("user_id", userRole.getUserId());
                maps.put("role_id", userRole.getRoleId());
                userRoleMapper.deleteByMap(maps);
            }
            ShiroAuthUtils.clearAllAuth();
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("用户角色授权失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("用户角色授权失败,请联系开发人员.");
        }
        return bizResult;
    }

    /**
     * 用户信息授权
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public BizResult<?> userInfoStateChange(String userId, Integer status) {
        BizResult<?> bizResult = new BizResult<>();
        try {
            // 判断是否删除
            if (StateConstants.UN_VALIDE.equals(status)) {
                // 删除用户角色数据
                Map<String, Object> maps = new HashMap<>();
                maps.put("user_id", userId);
                userRoleMapper.deleteByMap(maps);
            }
            // 修改用户信息
            userMapper.updateUserStatus(userId, status);
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("用户信息删除失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("用户信息删除失败,请联系开发人员.");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return bizResult;
    }

    /**
     * 用户重置密码
     *
     * @param userId
     * @return
     */
    @Override
    public BizResult<?> resetPwd(String userId, String pwd) {
        BizResult<?> bizResult = new BizResult<>();
        try {
            User user = new User();
            // 设置登录盐
            String salt = genId();
            // 设置用户信息
            user.setSalt(salt);
            user.setId(userId);
            // 根据盐加密用户密码
            user.setLoginPwd(new SimpleHash(CommonConstants.ENCRYP_TYPE,
                    // 判断密码是否为空
                    StringUtils.isNotBlank(pwd) ? pwd : CommonConstants.DEFAULT_PWD,
                    salt,
                    CommonConstants.ENCRYP_TIMES).toHex());
            //  添加用户信息
            userMapper.updateByPrimaryKeySelective(user);
            // 密码不为空,清空登录信息
            if (StringUtils.isNotBlank(pwd)) {
                Subject currentUser = SecurityUtils.getSubject();
                currentUser.logout();
            }
            bizResult.setSuccess(true);
        } catch (Exception e) {
            logger.error("用户信息删除失败,失败原因:" + e.getCause(), e);
            bizResult.setMsg("用户信息删除失败,请联系开发人员.");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return bizResult;
    }
}
